%%
%% This is file `tagpdf-mc-code-generic.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% tagpdf-mc-generic.dtx  (with options: `generic')
%% 
%% Copyright (C) 2019-2024 Ulrike Fischer
%% 
%% It may be distributed and/or modified under the conditions of
%% the LaTeX Project Public License (LPPL), either version 1.3c of
%% this license or (at your option) any later version.  The latest
%% version of this license is in the file:
%% 
%%    https://www.latex-project.org/lppl.txt
%% 
%% This file is part of the "tagpdf bundle" (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%% 
%% File: tagpdf-mc-generic.dtx
\ProvidesExplPackage {tagpdf-mc-code-generic} {2024-04-12} {0.99b}
 {part of tagpdf - code related to marking chunks - generic mode}
\tl_new:N \l__tag_mc_ref_abspage_tl

\tl_new:N \l__tag_mc_tmpa_tl

\newmarks  \g__tag_mc_marks
\seq_new:N \g__tag_mc_main_marks_seq
\seq_new:N \g__tag_mc_footnote_marks_seq
\seq_new:N \g__tag_mc_multicol_marks_seq

\seq_new:N  \l__tag_mc_firstmarks_seq
\seq_new:N  \l__tag_mc_botmarks_seq
\cs_new_protected:Npn \__tag_mc_begin_marks:nn #1 #2 %#1 tag, #2 label
  {
    \tex_marks:D \g__tag_mc_marks
      {
        b-, %first of begin pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        \g__tag_struct_stack_current_tl,  %structure num
        #1, %tag
        \bool_if:NT \l__tag_mc_key_stash_bool{stash}, % stash info
        #2, %label
      }
    \tex_marks:D \g__tag_mc_marks
      {
        b+, % second of begin pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        \g__tag_struct_stack_current_tl,  %structure num
        #1, %tag
        \bool_if:NT \l__tag_mc_key_stash_bool{stash}, % stash info
        #2, %label
      }
  }
\cs_generate_variant:Nn \__tag_mc_begin_marks:nn {oo}
\cs_new_protected:Npn \__tag_mc_artifact_begin_marks:n #1 %#1 type
  {
    \tex_marks:D \g__tag_mc_marks
      {
        b-, %first of begin pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        -1, %structure num
        #1 %type
      }
    \tex_marks:D \g__tag_mc_marks
      {
        b+, %first of begin pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        -1,  %structure num
        #1  %Type
      }
  }

\cs_new_protected:Npn \__tag_mc_end_marks:
  {
    \tex_marks:D \g__tag_mc_marks
      {
        e-, %first of end pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        \g__tag_struct_stack_current_tl,  %structure num
      }
    \tex_marks:D \g__tag_mc_marks
      {
        e+, %second of end pair
        \int_use:N\c@g__tag_MCID_abs_int, %mc-num
        \g__tag_struct_stack_current_tl,  %structure num
      }
  }
\cs_new_protected:Npn \__tag_mc_disable_marks:
 {
   \cs_set_eq:NN \__tag_mc_begin_marks:nn \use_none:nn
   \cs_set_eq:NN \__tag_mc_artifact_begin_marks:n \use_none:n
   \cs_set_eq:NN \__tag_mc_end_marks: \prg_do_nothing:
 }
\cs_new_protected:Npn \__tag_mc_get_marks:
 {
   \exp_args:NNe
   \seq_set_from_clist:Nn \l__tag_mc_firstmarks_seq
     { \tex_firstmarks:D \g__tag_mc_marks }
   \exp_args:NNe
   \seq_set_from_clist:Nn \l__tag_mc_botmarks_seq
     { \tex_botmarks:D   \g__tag_mc_marks }
 }
\cs_new_protected:Npn \__tag_mc_store:nnn #1 #2 #3 %#1 mc-prev, #2 mc-num #3 structure-num
  {
    %\prop_show:N \g__tag_struct_cont_mc_prop
    \prop_get:NnNTF \g__tag_struct_cont_mc_prop {#1} \l__tag_tmpa_tl
      {
        \prop_gput:Nne \g__tag_struct_cont_mc_prop {#1}{ \l__tag_tmpa_tl \__tag_struct_mcid_dict:n {#2}}
      }
      {
        \prop_gput:Nne \g__tag_struct_cont_mc_prop {#1}{ \__tag_struct_mcid_dict:n {#2}}
      }
    \prop_gput:Nee \g__tag_mc_parenttree_prop
      {#2}
      {#3}
  }
\cs_generate_variant:Nn \__tag_mc_store:nnn {eee}
\cs_new_protected:Npn \__tag_mc_insert_extra_tmb:n #1 % #1 stream: e.g. main or footnote
  {
     \__tag_check_typeout_v:n {=>~ first~ \seq_use:Nn \l__tag_mc_firstmarks_seq {,~}}
     \__tag_check_typeout_v:n {=>~ bot~ \seq_use:Nn \l__tag_mc_botmarks_seq {,~}}
     \__tag_check_if_mc_tmb_missing:TF
       {
         \__tag_check_typeout_v:n {=>~ TMB~ ~ missing~ --~ inserted}
         %test if artifact
         \int_compare:nNnTF { \seq_item:cn { g__tag_mc_#1_marks_seq } {3} } = {-1}
           {
              \tl_set:Ne \l__tag_tmpa_tl { \seq_item:cn { g__tag_mc_#1_marks_seq } {4} }
              \__tag_mc_handle_artifact:N \l__tag_tmpa_tl
           }
           {
              \exp_args:Ne
              \__tag_mc_bdc_mcid:n
                {
                  \seq_item:cn { g__tag_mc_#1_marks_seq } {4}
                }
              \str_if_eq:eeTF
                {
                  \seq_item:cn { g__tag_mc_#1_marks_seq } {5}
                }
                {}
                {
                  %store
                  \__tag_mc_store:eee
                    {
                      \seq_item:cn { g__tag_mc_#1_marks_seq } {2}
                    }
                    { \int_eval:n{\c@g__tag_MCID_abs_int} }
                    {
                      \seq_item:cn { g__tag_mc_#1_marks_seq } {3}
                    }
                }
                {
                   %stashed -> warning!!
                }
           }
       }
       {
         \__tag_check_typeout_v:n {=>~ TMB~ not~ missing}
       }
  }

\cs_new_protected:Npn \__tag_mc_insert_extra_tme:n #1 % #1 stream, eg. main or footnote
 {
   \__tag_check_if_mc_tme_missing:TF
     {
       \__tag_check_typeout_v:n {=>~ TME~ ~ missing~ --~ inserted}
       \__tag_mc_emc:
       \seq_gset_eq:cN
         {  g__tag_mc_#1_marks_seq }
         \l__tag_mc_botmarks_seq
     }
     {
       \__tag_check_typeout_v:n {=>~ TME~ not~ missing}
     }
 }
\cs_new_protected:Npn\__tag_add_missing_mcs:Nn #1 #2 {
  \vbadness \@M
  \vfuzz    \c_max_dim
  \vbox_set_to_ht:Nnn #1 { \box_ht:N #1 } {
    \hbox_set:Nn \l__tag_tmpa_box { \__tag_mc_insert_extra_tmb:n {#2} }
    \hbox_set:Nn \l__tag_tmpb_box { \__tag_mc_insert_extra_tme:n {#2} }
    \int_compare:nNnT {\l__tag_loglevel_int} > { 0 }
         {
           \seq_log:c { g__tag_mc_#2_marks_seq}
         }
    \box_set_ht:Nn \l__tag_tmpa_box \c_zero_dim
    \box_set_dp:Nn \l__tag_tmpa_box \c_zero_dim
    \box_set_ht:Nn \l__tag_tmpb_box \c_zero_dim
    \box_set_dp:Nn \l__tag_tmpb_box { \box_dp:N #1 }
    \boxmaxdepth \@maxdepth
    \box_use_drop:N        \l__tag_tmpa_box
    \vbox_unpack_drop:N     #1
    \tex_kern:D -\box_dp:N \l__tag_tmpb_box
    \nointerlineskip
    \box_use_drop:N \l__tag_tmpb_box
  }
}

\cs_new_protected:Npn \__tag_add_missing_mcs_to_stream:Nn #1#2
  {
    \__tag_check_if_active_mc:T {
    \vbadness\maxdimen
    \box_set_eq:NN \l__tag_tmpa_box #1
    \vbox_set_split_to_ht:NNn \l__tag_tmpa_box \l__tag_tmpa_box \c_max_dim
    \exp_args:NNe
    \seq_set_from_clist:Nn \l__tag_mc_firstmarks_seq
        { \tex_splitfirstmarks:D \g__tag_mc_marks }
    \seq_if_empty:NTF \l__tag_mc_firstmarks_seq
        {
          \__tag_check_typeout_v:n
            {
              No~ marks~ so~ use~ saved~ bot~ mark:~
              \seq_use:cn {g__tag_mc_#2_marks_seq} {,~} \iow_newline:
            }
           \seq_set_eq:Nc \l__tag_mc_firstmarks_seq {g__tag_mc_#2_marks_seq}
          \seq_set_eq:NN \l__tag_mc_botmarks_seq \l__tag_mc_firstmarks_seq
        }
        {
          \__tag_check_typeout_v:n
            {
              Pick~ up~ new~ bot~ mark!
            }
          \exp_args:NNe
          \seq_set_from_clist:Nn \l__tag_mc_botmarks_seq
              { \tex_splitbotmarks:D   \g__tag_mc_marks }
        }
    \__tag_add_missing_mcs:Nn #1 {#2}
%%
    \seq_gset_eq:cN  {g__tag_mc_#2_marks_seq} \l__tag_mc_botmarks_seq
%%
  }
}
\prg_new_conditional:Nnn \__tag_mc_if_in: {p,T,F,TF}
  {
    \bool_if:NTF \g__tag_in_mc_bool
      { \prg_return_true:  }
      { \prg_return_false: }
  }

\prg_new_eq_conditional:NNn \tag_mc_if_in: \__tag_mc_if_in: {p,T,F,TF}
\cs_set_eq:NN \__tag_mc_bmc:n  \pdf_bmc:n
\cs_set_eq:NN \__tag_mc_emc:   \pdf_emc:
\cs_set_eq:NN \__tag_mc_bdc:nn \pdf_bdc:nn
\cs_set_eq:NN \__tag_mc_bdc_shipout:ee \pdf_bdc_shipout:ee
\bool_if:NTF\g__tag_delayed_shipout_bool
  {
    \hook_gput_code:nnn {shipout/before}{tagpdf}{ \flag_clear:n { __tag/mcid } }
    \cs_set_protected:Npn \__tag_mc_bdc_mcid:nn #1 #2
      {
        \int_gincr:N \c@g__tag_MCID_abs_int
        \__tag_property_record:eV
         {
           mcid-\int_use:N \c@g__tag_MCID_abs_int
         }
         \c__tag_property_mc_clist
        \__tag_mc_bdc_shipout:ee
          {#1}
          {
            /MCID~\flag_height:n { __tag/mcid }
            \flag_raise:n { __tag/mcid }~  #2
          }
      }
  }
 {
   \msg_new:nnn { tagpdf } { old-engine }
    {
      The~engine~or~the~PDF management~is~too~old~or\\
      delayed~shipout~has~been~disabled.\\
      Fast~numbering~of~MC-chunks~not~available.\\
      More~compilations~will~be~needed~in~generic~mode.
    }
   \msg_warning:nn { tagpdf} { old-engine }
   \__tag_prop_new:N \g__tag_MCID_byabspage_prop
   \int_new:N \g__tag_MCID_tmp_bypage_int
   \cs_generate_variant:Nn \__tag_mc_bdc:nn {ne}
   \__tag_property_gset:nnnn {tagmcid } { now }
       {0}  { \int_use:N \g__tag_MCID_tmp_bypage_int }
   \cs_new_protected:Npn \__tag_mc_bdc_mcid:nn #1 #2
     {
       \int_gincr:N \c@g__tag_MCID_abs_int
       \tl_set:Ne \l__tag_mc_ref_abspage_tl
         {
           \__tag_property_ref:enn %3 args
             {
               mcid-\int_use:N \c@g__tag_MCID_abs_int
             }
             { tagabspage }
             {-1}
         }
       \prop_get:NoNTF
         \g__tag_MCID_byabspage_prop
         {
           \l__tag_mc_ref_abspage_tl
         }
         \l__tag_mc_tmpa_tl
         {
           %key already present, use value for MCID and add 1 for the next
           \int_gset:Nn \g__tag_MCID_tmp_bypage_int { \l__tag_mc_tmpa_tl }
           \__tag_prop_gput:Nee
             \g__tag_MCID_byabspage_prop
             { \l__tag_mc_ref_abspage_tl }
             { \int_eval:n {\l__tag_mc_tmpa_tl +1} }
         }
         {
           %key not present, set MCID to 0 and insert 1
           \int_gzero:N \g__tag_MCID_tmp_bypage_int
           \__tag_prop_gput:Nee
             \g__tag_MCID_byabspage_prop
             { \l__tag_mc_ref_abspage_tl }
             {1}
         }
       \__tag_property_record:eV
         {
           mcid-\int_use:N \c@g__tag_MCID_abs_int
         }
         \c__tag_property_mc_clist
        \__tag_mc_bdc:ne
          {#1}
          { /MCID~\int_eval:n { \g__tag_MCID_tmp_bypage_int }~ \exp_not:n { #2 } }
      }
 }
 \cs_new_protected:Npn \__tag_mc_bdc_mcid:n #1
  {
    \__tag_mc_bdc_mcid:nn {#1} {}
  }

\cs_new_protected:Npn \__tag_mc_handle_mcid:nn #1 #2 %#1 tag, #2 properties
  {
    \__tag_mc_bdc_mcid:nn {#1} {#2}
  }

\cs_generate_variant:Nn \__tag_mc_handle_mcid:nn {VV}

\cs_new_protected:Npn \__tag_mc_handle_stash:n #1 %1 mcidnum
  {
    \__tag_check_mc_used:n {#1}
    \__tag_struct_kid_mc_gput_right:nn
      { \g__tag_struct_stack_current_tl }
      {#1}
   \prop_gput:Nee \g__tag_mc_parenttree_prop
     {#1}
     { \g__tag_struct_stack_current_tl }
  }
\cs_generate_variant:Nn \__tag_mc_handle_stash:n { e }

\cs_new_protected:Npn  \__tag_mc_bmc_artifact:
  {
    \__tag_mc_bmc:n {Artifact}
  }
\cs_new_protected:Npn \__tag_mc_bmc_artifact:n #1
  {
    \__tag_mc_bdc:nn {Artifact}{/Type/#1}
  }
\cs_new_protected:Npn \__tag_mc_handle_artifact:N #1
   % #1 is a var containing the artifact type
  {
    \int_gincr:N \c@g__tag_MCID_abs_int
    \tl_if_empty:NTF #1
      { \__tag_mc_bmc_artifact: }
      { \exp_args:NV\__tag_mc_bmc_artifact:n #1 }
  }

\cs_new:Nn \__tag_get_data_mc_tag: { \g__tag_mc_key_tag_tl }
\cs_set_protected:Npn \tag_mc_begin:n #1 %#1 keyval
  {
    \__tag_check_if_active_mc:T
      {
        \group_begin: %hm
        \__tag_check_mc_if_nested:
        \bool_gset_true:N \g__tag_in_mc_bool
        \tl_set_eq:NN \l__tag_mc_key_tag_tl \g__tag_struct_tag_tl
        \tl_gset_eq:NN\g__tag_mc_key_tag_tl \g__tag_struct_tag_tl
        \keys_set:nn { __tag / mc } {#1}
        \bool_if:NTF \l__tag_mc_artifact_bool
          { %handle artifact
            \__tag_mc_handle_artifact:N \l__tag_mc_artifact_type_tl
            \exp_args:NV
            \__tag_mc_artifact_begin_marks:n \l__tag_mc_artifact_type_tl
          }
          { %handle mcid type
            \__tag_check_mc_tag:N  \l__tag_mc_key_tag_tl
            \__tag_mc_handle_mcid:VV
               \l__tag_mc_key_tag_tl
               \l__tag_mc_key_properties_tl
            \__tag_mc_begin_marks:oo{\l__tag_mc_key_tag_tl}{\l__tag_mc_key_label_tl}
            \tl_if_empty:NF {\l__tag_mc_key_label_tl}
              {
                \exp_args:NV
                \__tag_mc_handle_mc_label:e \l__tag_mc_key_label_tl
              }
            \bool_if:NF \l__tag_mc_key_stash_bool
              {
                \exp_args:NV\__tag_struct_get_parentrole:nNN
                    \g__tag_struct_stack_current_tl
                    \l__tag_get_parent_tmpa_tl
                    \l__tag_get_parent_tmpb_tl
                 \__tag_check_parent_child:VVnnN
                   \l__tag_get_parent_tmpa_tl
                   \l__tag_get_parent_tmpb_tl
                   {MC}{}
                   \l__tag_parent_child_check_tl
                \int_compare:nNnT {\l__tag_parent_child_check_tl}<{0}
                 {
                    \prop_get:cnN
                     { g__tag_struct_ \g__tag_struct_stack_current_tl _prop}
                     {S}
                     \l__tag_tmpa_tl
                    \msg_warning:nneee
                     { tag }
                     {role-parent-child}
                     { \l__tag_get_parent_tmpa_tl/\l__tag_get_parent_tmpb_tl  }
                     { MC~(real content) }
                     { not~allowed~
                       (struct~\g__tag_struct_stack_current_tl,~\l__tag_tmpa_tl)
                     }
                 }
                \__tag_mc_handle_stash:e { \int_use:N \c@g__tag_MCID_abs_int }
              }
          }
        \group_end:
      }
  }
\cs_set_protected:Nn \tag_mc_end:
  {
    \__tag_check_if_active_mc:T
      {
        \__tag_check_mc_if_open:
        \bool_gset_false:N \g__tag_in_mc_bool
        \tl_gset:Nn  \g__tag_mc_key_tag_tl { }
        \__tag_mc_emc:
        \__tag_mc_end_marks:
      }
  }

\keys_define:nn { __tag / mc }
  {
    tag .code:n = % the name (H,P,Span) etc
      {
        \tl_set:Ne   \l__tag_mc_key_tag_tl { #1 }
        \tl_gset:Ne  \g__tag_mc_key_tag_tl { #1 }
      },
    raw  .code:n =
      {
        \tl_put_right:Ne \l__tag_mc_key_properties_tl { #1 }
      },
    alt .code:n      = % Alt property
      {
        \str_set_convert:Noon
          \l__tag_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l__tag_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l__tag_mc_key_properties_tl { \l__tag_tmpa_str>~ }
      },
    alttext .meta:n = {alt=#1},
    actualtext .code:n      = % ActualText property
      {
        \tl_if_empty:oF{#1}
         {
           \str_set_convert:Noon
             \l__tag_tmpa_str
             { #1 }
             { default }
             { utf16/hex }
           \tl_put_right:Nn \l__tag_mc_key_properties_tl { /ActualText~< }
           \tl_put_right:No \l__tag_mc_key_properties_tl { \l__tag_tmpa_str>~ }
         }
      },
    label .tl_set:N        = \l__tag_mc_key_label_tl,
    artifact .code:n       =
      {
        \exp_args:Nne
          \keys_set:nn
            { __tag / mc }
            { __artifact-bool, __artifact-type=#1 }
      },
    artifact .default:n    = {notype}
  }
%% 
%%
%% End of file `tagpdf-mc-code-generic.sty'.
